/**
 * This class represents a warehouse
 */

/**
 * @author Maximilian Csuk
 * @author Bernhard Denner
 * @author Konrad Paumann
 *
 * $Revision: 70 $
 * $Date: 2007-10-21 12:24:06 +0000 (Sun, 21 Oct 2007) $
 */
import java.util.*;
import java.io.*;


public class Warehouse implements Displayable, Serializable {
	/**
	 * contains stored product groups
	 */
	private TreeMap<String, ProductGroup> assortment;
	
	/**
	 * constructor
	 */
	Warehouse() {
		assortment = new TreeMap<String, ProductGroup>();
	}
	
	/**
	 * returns a product group with a given name
	 * @param groupName name of the product group
	 * @return ProductGroup 
	 * @throws ProductException
	 */
	public ProductGroup getProductGroup(String groupName)
			throws ProductException {
		if (!assortment.containsKey(groupName)) {
			throw new ProductException("Das ist keine Produktgruppe");
		}
		return assortment.get(groupName);
	}
	
	/**
	 * adds a product group
	 * @param groupName Name of the new product group
	 * @param tax tax
	 * @throws ProductException
	 */
	public void addProductGroup(String groupName, int tax) 
			throws ProductException {
		if (assortment.containsKey(groupName)) {
			throw new ProductException("Produktgruppe schon vorhanden");
		}
		assortment.put(groupName, new ProductGroup(groupName, tax));
	}
	
	/**
	 * adds a product group
	 * @param g the group to add
	 * @throws ProductException
	 */
	public void addProductGroup(ProductGroup g) 
			throws ProductException {
		assert g != null;

		if (assortment.containsKey(g.getGroupName()))
			throw new ProductException("Produktgruppe schon vorhanden");
		
		assortment.put(g.getGroupName(), g);
	}
	
	/*
	 * removes an empty product group
	 * @param groupName
	 */
	public void removeProductGroup(String groupName) 
			throws ProductException {
		if (getProductGroup(groupName).isEmpty()) {
			if (assortment.remove(groupName) == null) {
				throw new ProductException("Produkt nicht gefunden"); 
			}
		} else {
			throw new ProductException("Produktgruppe ist noch nicht leer");
		}
	}
	
	/**
	 * adds a product
	 * 
	 * @param sDescription
	 * @param description
	 * @param price
	 * @param amount
	 * @throws ProductException
	 */
	public void addProduct(String productGroupName, String sDescription, 
			String description, int price, int amount) 
			throws ProductException {
		if (assortment.get(productGroupName).containsProduct(sDescription))
			throw new ProductException("Produkt bereits enthalten");
		assortment.get(productGroupName).addProduct(new Product(sDescription, description, price, amount));
	}
	
	/**
	 * adds a product
	 * 
	 * @param productGroupName the product-group to add the product to
	 * @param p the product to add
	 * @throws ProductException
	 */
	public void addProduct(String productGroupName, Product p) 
			throws ProductException {
		assert p != null;
		if (assortment.get(productGroupName).containsProduct(p.getShortDescription()))
			throw new ProductException("Produkt bereits enthalten");
		
		assortment.get(productGroupName).addProduct(p);
	}
	
	public void removeProduct(String productGroupName, String sDescription) 
			throws ProductException {
		ProductGroup g = assortment.get(productGroupName);
		if (g == null)
			throw new ProductException("Produktgruppe exisiert nicht");
		
		g.removeProduct(sDescription);
	}
	
	/**
	 * returns an iterator for the product groups
	 * @return Iterator<ProductGroup>
	 */
	public Iterator<ProductGroup> getPgIterator() {
		return assortment.values().iterator();
	}
	
	/**
	 * gets the string to be displayed
	 * 
	 * @return String with all product-groups
	 */
	public String getDisplayString() {
		String display = new String("");
		Iterator<String> it = assortment.keySet().iterator();
		while (it.hasNext()) {
			display += assortment.get(it.next()).getDisplayString() + "\n";
		}
		return display;
	}
	
	/*
	 * saves the complete warehouse to disk
	 * 
	 * @param filename the filename to save the warehouse to 
	 */
	public void serialize(String filename) {
		/*
		 * TODO:
		 * exception-handling, maybe with a special exception?
		 */
		
		FileOutputStream fs = null;
		try {
			fs = new FileOutputStream(filename);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		
	    try {
	    	ObjectOutputStream os = new ObjectOutputStream(fs);
	    	os.writeObject(assortment);
	        os.close();
	    } catch (IOException e) {
	    	e.printStackTrace();
	    }
	}
	
	/*
	 * retrieves a warehouse-file from disk
	 */
	public void deserialize(String filename) {
		/*
		 * TODO:
		 * exception-handling, maybe with a special exception?
		 */
		
		FileInputStream fs = null;
		try {
			fs = new FileInputStream(filename);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		
	    try {
	    	ObjectInputStream is = new ObjectInputStream(fs);
	    	Object object = is.readObject();
	    	assert object instanceof TreeMap;
	    	assortment = (TreeMap<String, ProductGroup>)object;
	        is.close();
	    } catch (IOException e) {
	    	e.printStackTrace();
	    } catch (ClassNotFoundException e) {
	    	e.printStackTrace();
	    }
	}
	
//	
//	/**
//	 * returns a product iterator
//	 */
//	public Iterator<Product> getProductIterator() {
//		return assortment.values().iterator();
//	}
}
